import Icon from '@/components/Icon'
import Input from '@/components/Input'
import NavBar from '@/components/NavBar'
import { Toast } from 'antd-mobile'
import { useEffect, useRef, useState } from 'react'
import styles from './index.module.scss'
import { io } from 'socket.io-client'
import { baseURL } from '@/utils/http'
import { getTokenInfo } from '@/utils/storage'

// 消息结构 - 用于书写提示和数据检查
type Message = {
  // 用于区别消息类型的 type
  type?: 'robot' | 'user'
  msg: string
  timestamp: number
}

export default function ProfileChat() {
  // 用于受控组件，收集输入框数据
  const [msg, setMsg] = useState('')

  // 聊天列表
  const [list, setList] = useState<Message[]>([])

  // 点击发送按钮
  const handleSend = () => {
    // 空提示
    if (!msg) return Toast.show({ content: '请输入内容.' })
    // 处理用户消息结构
    const userMsg: Message = {
      type: 'user',
      msg: msg,
      timestamp: Date.now(),
    }

    // 后端规定：发送与接收消息的事件(event) 均为 message
    // 发送消息用：  .emit('message')
    // 接收消息用:   .on('message')
    clientRef.current.emit('message', userMsg)
    // console.log('当前用户消息为', userMsg)
    // 后追加用户消息
    setList([...list, userMsg])
    // 清空输入框
    setMsg('')
  }

  const clientRef = useRef<any>(null)
  useEffect(() => {
    // 创建 socket.io 客户端实例
    const client = io(baseURL, {
      query: {
        token: getTokenInfo().token,
      },
      transports: ['websocket'],
    })

    // 存储到 ref 方便其他地方使用 client 实例
    clientRef.current = client

    // 首次连接 - 可用于做一些数据初始化
    client.on('connect', () => {
      // console.log('websocket连接成功+++')
      setList([
        { type: 'robot', msg: '亲爱的用户您好，小智同学为您服务。', timestamp: Date.now() },
        { type: 'user', msg: '你好啊。', timestamp: Date.now() + 1 },
      ])
    })

    // 后端规定：发送与接收消息的事件(event) 均为 message
    // 发送消息用：  .emit('message')
    // 接收消息用:   .on('message')
    client.on('message', (data) => {
      // console.log('收到消息', data)
      setList((oldList) => {
        return [...oldList, { type: 'robot', ...data }]
      })
    })

    // 清理函数
    return () => {
      // WebSocket 连接一旦建立就不会自动关闭，组件卸载时需要手动关闭连接
      client.close()
    }
  }, [])

  // 当 list 列表发生变化，滚动到底部
  useEffect(() => {
    window.scrollTo({
      // 页面有多高，就滚动多少
      top: document.body.scrollHeight,
      // behavior: 'smooth', 平滑滚动
      behavior: 'smooth',
    })
  }, [list])

  // 按回车键发送
  const handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      handleSend()
    }
  }

  return (
    <div className={styles.root}>
      {/* 顶部导航栏 */}
      <NavBar fixed>小智同学</NavBar>

      {/* 聊天记录列表 - 开始 */}
      <div className='chat-list'>
        {list.map((item) => {
          // 通过 type 区分消息类型
          if (item.type === 'robot') {
            return (
              <div key={item.timestamp} className='chat-item robot'>
                <Icon type='iconbtn_xiaozhitongxue' />
                <div className='message'>{item.msg}</div>
              </div>
            )
          } else {
            return (
              <div key={item.timestamp} className='chat-item user'>
                <img src={'http://toutiao.itheima.net/images/user_head.jpg'} alt='' />
                <div className='message'>{item.msg}</div>
              </div>
            )
          }
        })}
      </div>
      {/* 聊天记录列表 - 结束 */}

      {/* 底部消息输入框 */}
      <div className='footer'>
        <div className='input-footer'>
          <Icon type='iconbianji' />
          <Input
            autoFocus
            value={msg}
            onChange={(e) => setMsg(e.target.value)}
            className='no-border'
            placeholder='请描述您的问题'
            onKeyUp={(e) => handleKeyUp(e)}
          />
          <span onClick={handleSend} className='send'>
            发送
          </span>
        </div>
      </div>
    </div>
  )
}
